import { Modal } from 'antd';
import React, { forwardRef, Ref, useEffect, useState } from 'react';

interface InsertModalProps {
  onOk?: () => void;
  onCancel?: () => void;
}

/**
 * 如何封装一个弹框组件
 * 选择基于antd的弹框进行二次封装
 *
 *
 * 1、从零开发一个，弹框组件核心点要注意弹框的挂载位置，一般来说使用createPortal挂载到body元素下，这样不回收样式污染
 * 2、组件传值
 *    父组件如何调用子组件的方法，也就是如何调用组件内容的方法，让组件打开和关闭
 *    子组件如何暴漏出对应的事件如 确定事件、取消事件，父组件接收处理业务逻辑
 *
 * 3、性能优化
 *    避免不必要的渲染，使用React.memo包裹组件，只有当props变化时才会重新渲染组件
 *    注意：这样还会有一个问题？？
 *
 *
 * ref 就是父组件传过来的一个对象，我们可以把所有希望父组件可以使用或者说访问的方法、状态挂载到ref中供其父组件使用或者消费
 * @returns
 */
export const InsertModal = React.memo(
  forwardRef<InsertModalProps>((props: InsertModalProps, ref: any) => {
    const [isModalOpen, setIsModalOpen] = useState(false);

    const handleOk = () => {
      setIsModalOpen(false);
      props.onOk && props.onOk();
    };

    const handleCancel = () => {
      setIsModalOpen(false);
      props.onCancel && props.onCancel();
    };

    useEffect(() => {
      if (ref) {
        ref.current = {
          setIsModalOpen,
        };
      }
    }, [isModalOpen]);

    console.log('弹框重新渲染');

    return (
      <Modal title='新增' open={isModalOpen} onOk={handleOk} onCancel={handleCancel}>
        <p>Some contents...</p>
        <p>Some contents...</p>
        <p>Some contents...</p>
      </Modal>
    );
  })
);
